﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

using System.IO;
using System.IO.IsolatedStorage;
using System.Xml;
using System.Reflection;

namespace FolderHider
{
    /// <summary>
    /// Class for handle IsolatedStorage variables
    /// </summary>
    class InteropINVars
    {
        #region Vars
        XmlDocument _doc;
        IsolatedStorageFile _file;

        /// <summary>
        /// Return list of hidden folders
        /// </summary>
        public List<string> Folders
        {
            get
            {
                List<string> lista = new List<string>();

                foreach (XmlNode no in _doc.GetElementsByTagName("Folder"))
                    lista.Add(no.InnerText);

                return lista;
            }
        }
        public string KEY
        { get { return _doc.GetElementsByTagName("key")[0].InnerText; } }

        #endregion

        public InteropINVars(IsolatedStorageFile StoreFile)
        {
            _file = StoreFile;
            INI();
        }

        private void INI()
        {
            string[] tmpdata = _file.GetFileNames("data.xml");
            if (tmpdata.Length == 0) CreateNew();

            _doc = new XmlDocument();
            IsolatedStorageFileStream stream = new IsolatedStorageFileStream("data.xml", FileMode.Open, FileAccess.Read, _file);
            StreamReader rd = new StreamReader(stream);

            string p = rd.ReadLine();

            _doc.LoadXml(p);

            rd.Close();
            stream.Close();
        }
        private void CreateNew()
        {
            _doc = new XmlDocument();

            XmlNode root = _doc.CreateNode(XmlNodeType.Element, "root", null);

            XmlNode cmd = _doc.CreateNode(XmlNodeType.Element, "cmd", null);

            XmlNode help = _doc.CreateNode(XmlNodeType.Element, "help", null);
            help.InnerText = "Help";
            cmd.AppendChild(help);

            help = _doc.CreateNode(XmlNodeType.Element, "showlist", null);
            help.InnerText = "ShowList";
            cmd.AppendChild(help);

            help = _doc.CreateNode(XmlNodeType.Element, "changepass", null);
            help.InnerText = "ChangeKP";
            cmd.AppendChild(help);

            help = _doc.CreateNode(XmlNodeType.Element, "hide", null);
            help.InnerText = "FH";
            cmd.AppendChild(help);

            help = _doc.CreateNode(XmlNodeType.Element, "changecmd", null);
            help.InnerText = "ChgCMD";
            cmd.AppendChild(help);

            XmlNode pass = _doc.CreateNode(XmlNodeType.Element, "key", null);
            pass.InnerText = "pass";

            XmlNode fold = _doc.CreateNode(XmlNodeType.Element, "folders", null);

            root.AppendChild(cmd);
            root.AppendChild(pass);
            root.AppendChild(fold);
            _doc.AppendChild(root);

            IsolatedStorageFileStream stream = new IsolatedStorageFileStream("data.xml", FileMode.Create, _file);
            StreamWriter wrt = new StreamWriter(stream);
            wrt.Write(_doc.OuterXml);
            wrt.Flush();
            wrt.Close();
            stream.Close();
        }

        /// <summary>
        /// Get command index
        /// </summary>
        /// <param name="cmd">command</param>
        /// <returns>return int with index of command, -1 if invalid command</returns>
        public int GetCommandIndex(string cmd)
        {
            foreach (XmlNode n in _doc.GetElementsByTagName("cmd")[0].ChildNodes)
            {
                if (cmd == n.InnerText)
                {
                    switch(n.Name)
                    {
                        case "help":
                            return 0;
                        case "showlist":
                            return 1;
                        case "changepass":
                            return 2;
                        case "hide":
                            return 3;
                        case "changecmd":
                            return 4;
                    }
                }
            }

            return -1;
        }
        /// <summary>
        /// Change command to cmd
        /// </summary>
        /// <param name="cmd">new command string</param>
        /// <param name="index">index of command to change</param>
        public void SetCommand(string cmd, int index)
        {
            switch(index)
            {
                case 0:
                    _doc.GetElementsByTagName("help")[0].InnerText = cmd;
                    break;

                case 1:
                    _doc.GetElementsByTagName("showlist")[0].InnerText = cmd;
                    break;

                case 2:
                    _doc.GetElementsByTagName("changepass")[0].InnerText = cmd;
                    break;

                case 3:
                    _doc.GetElementsByTagName("hide")[0].InnerText = cmd;
                    break;

                case 4:
                    _doc.GetElementsByTagName("changecmd")[0].InnerText = cmd;
                    break;
            }

            Save();
        }
        /// <summary>
        /// get command string by index
        /// </summary>
        /// <param name="i">index of command to return</param>
        /// <returns>commad string, return null if invalid</returns>
        public string GetCommand(int i)
        {
            if (i < 0 || i > 4) return null;

            switch(i)
            {
                case 0:
                    return _doc.GetElementsByTagName("help")[0].InnerText;
                case 1:
                    return _doc.GetElementsByTagName("showlist")[0].InnerText;
                case 2:
                    return _doc.GetElementsByTagName("changepass")[0].InnerText;
                case 3:
                    return _doc.GetElementsByTagName("hide")[0].InnerText;
                case 4:
                    return _doc.GetElementsByTagName("changecmd")[0].InnerText;
            }

            return null;
        }

        /// <summary>
        /// Change current password
        /// </summary>
        /// <param name="pass">new password</param>
        public void ChangePass(string pass)
        {
            if (String.IsNullOrEmpty(pass)) return;
            _doc.GetElementsByTagName("key")[0].InnerText = pass;
        }
        /// <summary>
        /// Add new folder, to the list
        /// </summary>
        /// <param name="folderName"></param>
        public void AddFolder(string folderName)
        {
            List<string> _folders = new List<string>(Folders);

            if (_folders.Contains(folderName.ToLower())) return;

            XmlNode no = _doc.CreateNode(XmlNodeType.Element, "Folder", null);
            no.InnerText = folderName.ToLower();
            _doc.GetElementsByTagName("folders")[0].AppendChild(no);

            Save();
        }
        /// <summary>
        /// Remove folder from list
        /// </summary>
        /// <param name="folderName"></param>
        public void RemoveFolder(string folderName)
        {
            try
            {
                string p = "//Folder[text()='"+ folderName.ToLower() + "']";
                XmlNode no = _doc.SelectSingleNode(p);
                _doc.GetElementsByTagName("folders")[0].RemoveChild(no);
            }
            catch
            {

            }
        }

        /// <summary>
        /// save xml to memory
        /// </summary>
        public void Save()
        {
            IsolatedStorageFileStream stream = new IsolatedStorageFileStream("data.xml", FileMode.Create, _file);
            StreamWriter wrt = new StreamWriter(stream);
            wrt.Write(_doc.OuterXml);
            wrt.Flush();
            wrt.Close();
            stream.Close();
        }

        ~InteropINVars()
        {
            try
            {
                Save();
            }
            catch
            {

            }
        }
    }
}
